package myjava.strings;

public class Root {
   
   public static void main(String[] args) {
      
      /*
          # stringhe create con costruttore #
          ogni istanza ha uno spazio di memoria dedicato e == risulta falso
          perche' controlla l'indentita' dei due oggetti (puntano allo stesso spazio in memoria?)
          e non le lettere di cui sono composti! 
          [!] == risponde alla domanda "i due oggetti puntati da questi 2 reference sono lo stesso?"
      */
      String str1 = new String("x");
      String str2 = new String("x");
      System.out.println(str1 == str2); // false
      
      // per verificare l'ugualinza del contenuto delle 2 stringhe devo invece fare
      System.out.println(str1.equals(str2)); // true
      
      // faccio puntare i 2 reference allo stesso oggetto : adesso si che ottengo un true
      str2 = str1;
      System.out.println(str1 == str2); // true
         
      /*
          stringhe letterali, se composte dagli stessi caratteri,
          sono ancora oggetti ma puntano allo stesso spazio di memoria
          e, di conseguenza, l'uso di == funziona!
          Questo' e' un favore che ti fa la JVM per rendere disponibile il comportamento intuitivo di ==
          anche con le stringhe che pero', lo ricordiamo, sono degli oggetti e dovrebbero rispondere inaspettatamente all'uso di == 
          (che e' appunto cio' che fanno quando si usa il cosntruttore)

          CONSTANT POOL: le stringhe inizializzate usando la notazione letterale vengono messe in uno spazio di memoria speciale
                         in cui le istanze di una stessa stringa vengono minimizzate in un unico oggetto a cui le varie variabili
                         puntano. Il programmatore non lo "sa" e usa == per l significato intuitivo che esso ha */
      String str3 = "x";
      String str4 = "x";       
      String str5 = "x" + "";   
      System.out.println(str3 == str4); // true   
      // e persino:
      System.out.println(str3 == str5); // true
      // ... ma chiaramente anche questo:
      System.out.println(str3.equals(str5));

      /*
         # IMMUTABILITA'
         La classe String non fornisce nessun setter quindi una volta istanziata una stringa resta
         quella. Se provi a assegnare un'atra stringa al reference di una stringa 
         precedentemente istanziata quello che ottieni e' che il vecchio reference punta 
         ora al nuovo oggetto. Es: */
      String str6 = "ciao";
      String str7;
      // faccio puntare str7 allo stesso oggetto puntato da str6  
      str7 = str6;
      // PROVO(!) a sovrascrivere str6 ma questo non acccade perche str6 e' immutabile.
      // quello che accade e che ridireziono il puntatore str6 sulla stringa "mondo"
      str6 = "mondo";
      System.out.println(str6); // mondo
      // str7 e' ancora "ciao" a testimonianza del fatto che l'istruzione <str6 = "mondo";>
      // non ha cambiato l'oggetto stringa "ciao" ma lo ha solo DEREFERENZIATO da str6!
      System.out.println(str7);
       
   }

}